package com.own.business.sync.trigger.store.core;

import com.alibaba.fastjson2.JSON;
import com.own.business.sync.trigger.base.config.SyncTriggerPollingCondition;
import com.own.business.sync.trigger.base.entity.SyncTrigger;
import com.own.business.sync.trigger.base.mapper.SyncTriggerMapper;
import com.own.business.sync.trigger.base.property.SyncTriggerProperty;
import com.own.business.sync.trigger.base.service.SyncTriggerService;
import com.own.component.common.util.executor.ExecutorUtil;
import com.own.component.store.core.Store;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.stream.Collectors;

/**
 * SyncTriggerStoreCoreTask
 * <p>
 * 启动完成后开始执行
 *
 * @author chenxueli
 * @date 2024-01-09 17:30:42
 */
@Slf4j
@Component
@Conditional(SyncTriggerPollingCondition.class)
public class SyncTriggerStoreCoreTask {

    private final Object lock = new Object();
    @Resource
    private SyncTriggerProperty syncTriggerProperty;
    @Resource
    private SyncTriggerService syncTriggerService;
    @Resource
    private SyncTriggerMapper syncTriggerMapper;
    @Resource
    private ExecutorUtil executorUtil;
    @Resource
    private Store<String> store;

    @PostConstruct
    public void init() {
        executorUtil.execute(this::polling);
    }

    /**
     * 轮询信息
     */
    @SuppressWarnings("all")
    private void polling() {
        var key = syncTriggerProperty.getStoreKey();
        var max = syncTriggerProperty.getPollingTimeList().length - 1;
        // 采用while true的方式可以避免使用递归方式造成的栈溢出的问题
        var c = 0;
        while (true) {
            synchronized (lock) {
                var list = syncTriggerService.listForLimit();
                if (!list.isEmpty()) {
                    // 批量序列化，存入缓存
                    var addList = list.stream().map(item -> JSON.toJSONString(item)).collect(Collectors.toList());
                    store.list().add(key, addList);
                    // 删除数据
                    var idList = list.stream().map(SyncTrigger::getId).collect(Collectors.toList());
                    syncTriggerMapper.deleteBatchIds(idList);
                    log.info("批量处理完成，数量:{}", list.size());
                    c = 0;
                } else {
                    var index = Math.min(c, max);
                    var timeout = syncTriggerProperty.getPollingTimeList()[index];
                    log.info("未查询到调整的数据，开始休眠" + timeout + "ms");
                    try {
                        lock.wait(timeout);
                        c++;
                    } catch (InterruptedException e) {
                        log.error("等待异常", e);
                    }
                }
            }
        }
    }

}
